/*
 * PointResource.cpp
 *
 *  Created on: 2013. 9. 26.
 *      Author: mega@gamevil.com
 */

#include "../User.h"
#include "../engine.h"
#include "../NUtil/Utils.h"
#include "../NLogic/Space.h"
#include "../NLogic/Party.h"

#include "Static.h"

#include "PointResource.h"

namespace ProjectZ { namespace NResource {

PointResource::PointResource()
{
	pPointAD	= new PointData;
	pPointIOS	= new PointData;
}

PointResource::~PointResource()
{
	delete pPointAD;
	delete pPointIOS;
}

bool PointResource::LoadResource()
{
	if (false == pPointAD->LoadResource(MARKET_GOOGLE, SC_KAKAO_GOOGLE))
		return false;

	if (false == pPointIOS->LoadResource(MARKET_IOS, SC_KAKAO_IOS))
		return false;

	return true;
}

PointData::Flyweight * PointResource::GetFly(int company, int saleCode, int level)
{
	NUtil::MarketType marketType = NUtil::GetMarketType(company, saleCode);

	switch (marketType)
	{
	case NUtil::MarketType::AD_KAKAO:
		return pPointAD->GetFly(level);

	case NUtil::MarketType::IOS_KAKAO:
		return pPointIOS->GetFly(level);

	default:
		return NULL;
	}

	return NULL;
}


PointData::~PointData()
{
	std::for_each(clsFlyTree.begin(), clsFlyTree.end(), ProjectZ::NUtil::del_second_ptr<DATATREE::value_type>);
}

void
PointData::Clear()
{
	std::for_each(clsFlyTree.begin(), clsFlyTree.end(), ProjectZ::NUtil::del_second_ptr<DATATREE::value_type>);
	clsFlyTree.clear();
}

bool PointData::LoadResource(int company, int saleCode)
{
	::Database::Command::Auto clsAuto(::Database::GETCOMMANDPOOL());
	clsAuto->SetQueryType(::Database::Command::SELECT);
	clsAuto->MakeQuery("SELECT * FROM resource_point_reward WHERE company=%d AND sale_cd=%d", company, saleCode);

	if (false == ::Database::GETSESSION()->SyncExecute(1, clsAuto))
		return false;

	if( clsAuto->GetErrorIdx() != 0 )
		return false;

	if (0 == clsAuto->ResultRowCount())
		return false;

	Clear();

	while( clsAuto->Next() )
	{
		::Toolkit::Str<3> NATIONAL_CODE;
		int seq = 0;
		int tmpCompany = 0;
		int tmpSaleCode = 0;

		PointData::Flyweight * pFly = new PointData::Flyweight;

		clsAuto->GetRecord() >> NATIONAL_CODE >> seq >> tmpCompany >> tmpSaleCode >> pFly->_MIN_LEVEL >> pFly->_MAX_LEVEL
				>> pFly->_WIN_LOW_WP >> pFly->_WIN_SAME_WP >> pFly->_WIN_HIGH_WP >> pFly->_WIN_BEST_WP
				>> pFly->_LOSE_LOW_WP >> pFly->_LOSE_SAME_WP >> pFly->_LOSE_HIGH_WP >> pFly->_LOSE_BEST_WP
				>> pFly->_WIN_LOW_EP >> pFly->_WIN_SAME_EP >> pFly->_WIN_HIGH_EP >> pFly->_WIN_BEST_EP
				>> pFly->_LOSE_LOW_EP >> pFly->_LOSE_SAME_EP >> pFly->_LOSE_HIGH_EP >> pFly->_LOSE_BEST_EP
				>> pFly->_PK_FIRST_EP >> pFly->_PK_SECOND_EP >> pFly->_PK_THIRD_EP >> pFly->_PK_FORTH_EP;

		if (0 != Config::Instance().GetResourceDatabase()._strNational.compare(NATIONAL_CODE.c_str()))
		{
			DEBUGLOG("%s:%d NATIONAL_CODE ERROR!!! Config National Code [%s] , Resource National Code [%s]",
					__FILE__, __LINE__,
					Config::Instance().GetResourceDatabase()._strNational.c_str(),
					NATIONAL_CODE.c_str());
			return false;
		}

		clsFlyTree[pFly->_MIN_LEVEL] = pFly;
	}

	return true;
}

PointData::Flyweight * PointData::GetFly(int level)
{
	int levelRange = 1;

	if (level >= 10)
		levelRange = (level / 10) * 10;

	auto iter = clsFlyTree.find(levelRange);

	if (iter == clsFlyTree.end())
		return NULL;

	return iter->second;
}

int PointResource::PVPWinPoint(User * pUser, User * pOppUser, bool bWin)
{
	NLogic::Space * pSpace = pUser->GetSpace();

	if (pSpace == NULL)
		return 0;

	PointData::Flyweight * pFly = this->GetFly(pUser->GetUserInfo().company, pUser->GetUserInfo().sale_code, pUser->GetCharacterInfo().level);

	if (pFly == NULL)
		return 0;

	MatchingResource * pMatching = NResource::Static::InstancePtr()->GetMatching();

	if (pMatching == NULL)
		return 0;

	if (pMatching->IsLowGrade(pUser, pOppUser))
		return bWin ? pFly->_WIN_LOW_WP : pFly->_LOSE_LOW_WP;

	if (pMatching->IsSameGrade(pUser, pOppUser))
		return bWin ? pFly->_WIN_SAME_WP : pFly->_LOSE_SAME_WP;

	if (pMatching->IsHighGrade(pUser, pOppUser))
		return bWin ? pFly->_WIN_HIGH_WP : pFly->_LOSE_HIGH_WP;

	if (pMatching->IsBestGrade(pUser, pOppUser))
		return bWin ? pFly->_WIN_BEST_WP : pFly->_LOSE_BEST_WP;

	return 0;
}

int PointResource::PVPEvolvePoint(User * pUser, User * pOppUser, bool bWin)
{
	NLogic::Space * pSpace = pUser->GetSpace();

	if (pSpace == NULL)
		return 0;

	PointData::Flyweight * pFly = this->GetFly(pUser->GetUserInfo().company, pUser->GetUserInfo().sale_code, pUser->GetCharacterInfo().level);

	if (pFly == NULL)
		return 0;

	MatchingResource * pMatching = NResource::Static::InstancePtr()->GetMatching();

	if (pMatching == NULL)
		return 0;

	if (pMatching->IsLowGrade(pUser, pOppUser))
		return bWin ? pFly->_WIN_LOW_EP : pFly->_LOSE_LOW_EP;

	if (pMatching->IsSameGrade(pUser, pOppUser))
		return bWin ? pFly->_WIN_SAME_EP : pFly->_LOSE_SAME_EP;

	if (pMatching->IsHighGrade(pUser, pOppUser))
		return bWin ? pFly->_WIN_HIGH_EP : pFly->_LOSE_HIGH_EP;

	if (pMatching->IsBestGrade(pUser, pOppUser))
		return bWin ? pFly->_WIN_BEST_EP : pFly->_LOSE_BEST_EP;

	return 0;
}

int PointResource::PKEvolvePoint(User * pUser, int myRank)
{
	NLogic::Space * pSpace = pUser->GetSpace();

	if (pSpace == NULL)
		return 0;

	NResource::BalanceResource * balanceResource = NResource::Static::InstancePtr()->GetBalance();
	unsigned int dailyEPMax = balanceResource->GetValue(pUser, EM_DAILY_MAX_EVOLUTION_POINT);

	if( dailyEPMax <= pUser->GetCharacterInfo().daily_ep )
		return 0;

	PointData::Flyweight * pFly = this->GetFly(pUser->GetUserInfo().company, pUser->GetUserInfo().sale_code, pUser->GetCharacterInfo().level);

	if (pFly == NULL)
		return 0;

	int playerCount = static_cast<int>(pSpace->GetBattleTree().size());

	if (playerCount < 3)
		return 0;

	time_t curtime = time(NULL);
	pUser->SetDailyEPTime(curtime);

	int ep = 0;
	if (playerCount == 3)
	{
		switch (myRank)
		{
		case 1: ep = pFly->_PK_SECOND_EP; break;
		case 2: ep = pFly->_PK_THIRD_EP; break;
		case 3: ep = pFly->_PK_FORTH_EP; break;
		}
	}
	else if (playerCount == 4)
	{
		switch (myRank)
		{
		case 1: ep = pFly->_PK_FIRST_EP; break;
		case 2: ep = pFly->_PK_SECOND_EP; break;
		case 3: ep = pFly->_PK_THIRD_EP; break;
		case 4: ep = pFly->_PK_FORTH_EP; break;
		}
	}

	if( 0 > ep )
		ep = 0;

	if(dailyEPMax < pUser->GetCharacterInfo().daily_ep + ep)
		ep = dailyEPMax - pUser->GetCharacterInfo().daily_ep;


	return ep;
}

} /*NResource*/ } /* namespace ProjectZ */



